home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /* $Revision: 1.3 $ */
- /* compile: cc -o xmblur xmblur.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
- #include <stdlib.h>
- #include <stdio.h>
- #include <Xm/Form.h>
- #include <Xm/Frame.h>
- #include <GL/GLwMDrawA.h>
- #include <X11/keysym.h>
- #include <X11/Xutil.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glx.h>
-
- static int snglBuf[] =
- {
- GLX_RGBA,
- GLX_ACCUM_RED_SIZE, 8,
- GLX_ACCUM_GREEN_SIZE, 8,
- GLX_ACCUM_BLUE_SIZE, 8,
- None
- };
-
- static int dblBuf[] =
- {
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_ACCUM_RED_SIZE, 8,
- GLX_ACCUM_GREEN_SIZE, 8,
- GLX_ACCUM_BLUE_SIZE, 8,
- None
- };
-
- static String fallbackResources[] =
- {
- "*title: OpenGL motion blur demo",
- "*glxarea*width: 300", "*glxarea*height: 300",
- "*frame*x: 20", "*frame*y: 20",
- "*frame*topOffset: 20", "*frame*bottomOffset: 20",
- "*frame*rightOffset: 20", "*frame*leftOffset: 20",
- "*frame*shadowType: SHADOW_IN",
- NULL
- };
-
- GLfloat angleX = 15.0, angleY = 12.0;
- GLboolean doubleBuffer = GL_TRUE;
-
- Display *dpy;
- XtAppContext app;
- Widget toplevel, form, frame, glxarea;
- XVisualInfo *visinfo;
- GLXContext glxcontext;
- XFontStruct *xfont;
- int firstChar, lastChar;
- GLuint fontBase;
- char *status;
- GLboolean doBlur;
- GLUquadricObj *quadObj;
-
- void
- setBlur(GLboolean blurMode)
- {
- doBlur = blurMode;
- if (doBlur) {
- status = "Blur: enabled";
- glClear(GL_ACCUM_BUFFER_BIT); /* blow away accumulation contents */
- } else {
- status = "Blur: disabled";
- }
- }
-
- void
- drawScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT);
- /*
- * Draw the wireframe cylinder.
- */
- glColor3f(1.0, 0.0, 0.0);
- glPushMatrix();
- glRotatef(angleX, 1.0, 0.0, 0.0);
- glRotatef(angleY, 0.0, 1.0, 0.0);
- glCallList(1);
- glPopMatrix();
- /*
- * Use accumulation buffer for motion blurring.
- */
- if (doBlur) {
- /*
- * Be careful not to overflow the accumulation buffer; GL_RETURN is
- * the only accumulation buffer operation defined to do clamping.
- * Don't assume GL_MULT or GL_ACCUM clamp.
- */
- glAccum(GL_MULT, 0.8);
- glAccum(GL_ACCUM, 0.2);
- /*
- * Renormalize the return by multipling the accumulation buffer
- * contents by 5.
- */
- glAccum(GL_RETURN, 5.0);
- }
- /*
- * Print out instructions and blur mode.
- */
- #define HELP1 "Push 's' to step frame"
- #define HELP2 "Push 'b' toggles blur"
- glColor3f(1.0, 1.0, 0.0);
- glRasterPos2i(-14, 13);
- glCallLists(sizeof(HELP1) - 1, GL_UNSIGNED_BYTE, HELP1);
- glColor3f(1.0, 1.0, 0.0);
- glRasterPos2i(-14, 11);
- glCallLists(sizeof(HELP2) - 1, GL_UNSIGNED_BYTE, HELP2);
- glColor3f(0.0, 1.0, 0.0);
- glRasterPos2i(-14, -14);
- glCallLists(strlen(status), GL_UNSIGNED_BYTE, (unsigned char *) status);
- /*
- * Swap the buffer if we are double buffering.
- */
- if (doubleBuffer)
- GLwDrawingAreaSwapBuffers(glxarea);
- /*
- * Finish to ensure we aren't buffering up too much work.
- */
- glFinish();
- }
-
- void
- input_callback(Widget w, XtPointer client_data, XtPointer call)
- {
- char buffer[31];
- KeySym keysym;
- GLwDrawingAreaCallbackStruct *call_data;
- XComposeStatus composeStatus;
-
- call_data = (GLwDrawingAreaCallbackStruct *) call;
-
- switch (call_data->event->type) {
- case KeyPress:
- XLookupString(&call_data->event->xkey, buffer,
- 30, &keysym, &composeStatus);
- switch (keysym) {
- case XK_Escape:
- exit(0);
- break;
- case XK_B:
- case XK_b:
- setBlur(!doBlur); /* toggle blur mode */
- drawScene();
- break;
- case XK_S:
- case XK_s:
- angleX += 15.0;
- angleY += 12.0;
- if (angleX >= 360.0)
- angleX = 0.0;
- if (angleY >= 360.0)
- angleY = 0.0;
- drawScene();
- break;
- }
- break;
- }
- }
-
- void
- resize_callback(Widget w, XtPointer client_data, XtPointer call)
- {
- GLwDrawingAreaCallbackStruct *call_data;
- call_data = (GLwDrawingAreaCallbackStruct *) call;
-
- glViewport(0, 0, call_data->width, call_data->height);
- }
-
- void
- expose_callback(Widget w, XtPointer client_data, XtPointer call)
- {
- GLwDrawingAreaCallbackStruct *call_data;
- call_data = (GLwDrawingAreaCallbackStruct *) call;
-
- if (doBlur) {
- /*
- * Can't trust the contents of the accumulation buffer after
- * an expose. Note: this makes xmblur regenerate itself after
- * an expose properly if blur is enabled.
- */
- glClear(GL_ACCUM_BUFFER_BIT);
- }
- drawScene();
- }
-
- void
- init_callback(Widget w, XtPointer client_data, XtPointer call)
- {
- XVisualInfo *visinfo;
-
- XtVaGetValues(w, GLwNvisualInfo, &visinfo, NULL);
- glxcontext = glXCreateContext(XtDisplay(w), visinfo,
- /* no sharing */ 0, /* direct if possible */ GL_TRUE);
- }
-
- main(int argc, char **argv)
- {
- toplevel = XtAppInitialize(&app, "Glxwidget", NULL, 0, &argc, argv,
- fallbackResources, NULL, 0);
- dpy = XtDisplay(toplevel);
- form = XmCreateForm(toplevel, "form", NULL, 0);
- XtManageChild(form);
- frame = XmCreateFrame(form, "frame", NULL, 0);
- XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
- XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
- XmNrightAttachment, XmATTACH_FORM, NULL);
- XtManageChild(frame);
- /*
- * We find the XVisualInfo* we want for the GLwMDrawA widget _before_ we
- * create the widget. The alternative to this is specifying the OpenGL
- * visual attributes as resources arguments when creating the widget but
- * unfortunately, if a visual matching the attributes we specify does not
- * exist, we get a fatal error message like:
- *
- * Error: GLwMDrawingArea: requested visual not supported
- *
- * By specifying exactly which XVisualInfo* we want, we avoid this problem,
- * allowing us to fall back to another acceptable set of visual
- * attirbutes (single buffered in this case) and print out our own more
- * informative message if even the second visual selection fails.
- */
- visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
- if (visinfo == NULL) {
- visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
- if (visinfo == NULL)
- XtAppError(app, "no RGB visual with accumulation buffer");
- doubleBuffer = GL_FALSE;
- }
- /*
- * Load the desired font.
- */
- xfont = XLoadQueryFont(dpy, "9x15");
- if (xfont == NULL) {
- XtAppError(app, "no 9x15 font found");
- }
- glxarea = XtVaCreateManagedWidget("glxarea", glwMDrawingAreaWidgetClass,
- frame, GLwNvisualInfo, visinfo, NULL);
- XtAddCallback(glxarea, GLwNginitCallback, init_callback, NULL);
- XtAddCallback(glxarea, GLwNexposeCallback, expose_callback, NULL);
- XtAddCallback(glxarea, GLwNresizeCallback, resize_callback, NULL);
- XtAddCallback(glxarea, GLwNinputCallback, input_callback, NULL);
- XtRealizeWidget(toplevel);
- GLwDrawingAreaMakeCurrent(glxarea, glxcontext);
- /*
- * Make cylinder display list.
- */
- quadObj = gluNewQuadric();
- gluQuadricDrawStyle(quadObj, GLU_LINE);
- glNewList(1, GL_COMPILE);
- gluCylinder(quadObj, 2.0, 5.0, 10.0, 10, 4);
- glEndList();
- /*
- * Now the GLwNginitCallback has been called so the OpenGL context has
- * been set up. Now we can initialize the X font as a set of OpenGL
- * display lists.
- */
- firstChar = xfont->min_char_or_byte2;
- lastChar = xfont->max_char_or_byte2;
- glXUseXFont(xfont->fid, firstChar, lastChar - firstChar + 1,
- /* base display list of glyphs */ 2
- /* since 1 is used for the cylinder */);
- glListBase(2 - firstChar);
- /*
- * Initialize OpenGL state.
- */
- glViewport(0, 0, 300, 300); /* XXX work around Reality Engine bug */
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClearAccum(0.0, 0.0, 0.0, 0.0);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- setBlur(GL_FALSE);
- /*
- * Start dispatching X events...
- */
- XtAppMainLoop(app);
- }
-